#include "World.h"

World::World()
:perso("Anthony", "TheBoss", "Images/face2.png", "Images/Hugo.png"), map("map.txt"),
    worldWindow(VideoMode(MAIN_WIDTH, MAIN_HEIGHT), "World Window"/*, Style::Fullscreen*/), view(FloatRect(0.f,0.f,(float)MAIN_WIDTH,(float)MAIN_HEIGHT)), dial()
{
    taux = 10.0;
    perso.setPosition(6*32,8*32);
    map.setPnj(perso.getCaseX(), perso.getCaseY(), true);

    worldWindow.SetFramerateLimit(60);
    worldWindow.EnableKeyRepeat(true);


    view.SetCenter((float)perso.getPositionX(), (float)perso.getPositionY());
    worldWindow.SetView(view);

    nbPnj = 3;
    pnj = new Pnj[nbPnj];
    for(int i=0; i < nbPnj; i++)
        map.setPnj(pnj[i].getCaseX(), pnj[i].getCaseY(), true);
    pnj[2].setCanMove(false);
    pnj[0].setName("Sieo"); pnj[0].setSurname("Hugo");
    pnj[1].setName("Arkane"); pnj[1].setSurname("JP");
    pnj[2].setName("Oristal"); pnj[2].setSurname("Titou");
}

World::~World()
{
        delete [] pnj;
}

void World::main()
{
    map.setZone(10,8,5,3,"sand_dirt");

    while (worldWindow.IsOpened())
    {
        // Process events

        while ( worldWindow.GetEvent(event) )
        {
        // Close window : exit

            if ((event.Type == sf::Event::KeyPressed) && (event.Key.Code == sf::Key::Escape))
                {
                    worldWindow.Close();
                }
            else if ((event.Type == sf::Event::KeyPressed) && (event.Key.Code == sf::Key::A))
            {
                searchInteraction();
            }

        }


        if ((event.Type == sf::Event::KeyPressed) && (event.Key.Code == sf::Key::Left))
            {
                if(perso.askAnim(MOVE_LEFT, map.canMoveOn(perso.getPositionX(), perso.getPositionY(), MOVE_LEFT)))
                {
                    map.setPnj(perso.getCaseX(), perso.getCaseY(), false);
                    map.setPnj(perso.getDestCaseX(), perso.getDestCaseY(), true);
                    rencontre();
                }
            }
        else if ((event.Type == sf::Event::KeyPressed) && (event.Key.Code == sf::Key::Right))
            {
                if(perso.askAnim(MOVE_RIGHT,  map.canMoveOn(perso.getPositionX(), perso.getPositionY(), MOVE_RIGHT)))
                {
                    map.setPnj(perso.getCaseX(), perso.getCaseY(), false);
                    map.setPnj(perso.getDestCaseX(), perso.getDestCaseY(), true);
                    rencontre();
                }
            }
        else if ((event.Type == sf::Event::KeyPressed) && (event.Key.Code == sf::Key::Up))
            {
                if(perso.askAnim(MOVE_UP,  map.canMoveOn(perso.getPositionX(), perso.getPositionY(), MOVE_UP)))
                {
                    map.setPnj(perso.getCaseX(), perso.getCaseY(), false);
                    map.setPnj(perso.getDestCaseX(), perso.getDestCaseY(), true);
                    rencontre();
                }
            }
        else if ((event.Type == sf::Event::KeyPressed) && (event.Key.Code == sf::Key::Down))
            {
                if(perso.askAnim(MOVE_DOWN,  map.canMoveOn(perso.getPositionX(), perso.getPositionY(), MOVE_DOWN)))
                {
                    map.setPnj(perso.getCaseX(), perso.getCaseY(), false);
                    map.setPnj(perso.getDestCaseX(), perso.getDestCaseY(), true);
                    rencontre();
                }
            }

        draw();
        // Update the window
        worldWindow.Display();
    }
}

void World::movePnj()
{
    for(int i=0; i < nbPnj; i++)
    {
            if((rand()%100)==1)
            {
                int d = rand()%4;
                if(pnj[i].askAnim( d, map.canMoveOn(pnj[i].getPositionX(), pnj[i].getPositionY(), d)))
                {
                    map.setPnj(pnj[i].getCaseX(), pnj[i].getCaseY(), false);
                    map.setPnj(pnj[i].getDestCaseX(), pnj[i].getDestCaseY(), true);

                }
            }
    }
}

void World::searchInteraction()
{
        bool b = false;

        int i = 0;
        while(not b and i<nbPnj)
        {
            if(perso.getDestCaseX() == pnj[i].getCaseX() and perso.getDestCaseY() == pnj[i].getCaseY())
            {
                if(!pnj[i].getIsMoving())
                {
                    dialogue(pnj[i]);
                }
                b = true;
            } else i++;
        }
}

void World::draw()
{
     worldWindow.Clear(COLOR_BLACK);
        view.SetCenter((float)perso.getPositionX(), (float)perso.getPositionY());
        movePnj();

        // Draw the sprite
        worldWindow.Draw(map.getSprite());
        for(int i = 0; i<nbPnj; i++)
            worldWindow.Draw(pnj[i].getPnjMovement());
        worldWindow.Draw(perso.getPnjMovement());
}

void World::dialogue(Pnj& p)
{
    bool d = false;
    p.setIsMoving(true);
    p.rotate((perso.getDirection()+2)%4);

    draw();
    dial.searchDial(p.getName(), p.getSurname());
    dial.draw(worldWindow, p, perso);
    worldWindow.Display();

    while(not d)
    {



        worldWindow.GetEvent(event);
        if((event.Type == sf::Event::KeyPressed) && (event.Key.Code == sf::Key::Z))
        {

            if(dial.endRead())
            {
                p.setIsMoving(false);
                d = true;
            }
            else
            {
                draw();
                dial.draw(worldWindow, p, perso);
                worldWindow.Display();
            }

        }
    }
}

RenderWindow& World::getWorldWindow()
{
    return worldWindow;
}

void World::rencontre() {
    if (!(map.getBlock(perso.getCaseX(),perso.getCaseY()).isPossible()) && (map.getBlock(perso.getDestCaseX(),perso.getDestCaseY()).isPossible())) {   // Si hors zone & dest = zone
        taux = TAUX_RECONTRE;
        cout << "Taux actuel: " << taux << endl;
        if ((rand()%100) <= taux) {
            cout << "RENCONTRE!!" << endl;
            taux = TAUX_RECONTRE - TAUX_RECONTRE_INCR;
        }
    }
    else if (map.getBlock(perso.getCaseX(),perso.getCaseY()).isPossible() && map.getBlock(perso.getDestCaseX(),perso.getDestCaseY()).isPossible()) {   // Si dans une zone & dest = zone
        taux = taux + TAUX_RECONTRE_INCR;
        cout << "Taux actuel: " << taux << endl;
        if ((rand()%100) <= taux) {
            cout << "RENCONTRE!!" << endl;
            taux = TAUX_RECONTRE - TAUX_RECONTRE_INCR;
        }
    }
    else if (map.getBlock(perso.getCaseX(),perso.getCaseY()).isPossible() && !(map.getBlock(perso.getDestCaseX(),perso.getDestCaseY()).isPossible())) { // Si zone & dest = hors zone
        taux = 0.0;
        cout << "Taux actuel: " << taux << endl;
    }
}
